{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pickle\n",
    "import pandas as pd\n",
    "import seaborn as sns\n",
    "import matplotlib.pyplot as plt\n",
    "name_map = {\n",
    "    \"arima\": \"ARIMA\",\n",
    "    \"TCN\": \"TCN\",\n",
    "    \"N-HiTS\": \"N-HiTS\",\n",
    "    \"text-davinci-003\": \"GPT-3\\n(interp.)\",\n",
    "    \"text-davinci-003-Nan\": \"GPT-3\\n(NaNs)\"\n",
    "}\n",
    "\n",
    "with open('eval/missing_expt/missing.pkl','rb') as f:\n",
    "    all_output = pickle.load(f)\n",
    "\n",
    "df = []\n",
    "for dataset in all_output:\n",
    "    print(dataset)\n",
    "    for method in all_output[dataset]:\n",
    "        print(method)\n",
    "        \n",
    "        if method == 'p':\n",
    "            continue\n",
    "\n",
    "        gpt_nll = all_output[dataset]['text-davinci-003-Nan'][0]\n",
    "\n",
    "        probs = all_output[dataset]['p']\n",
    "        nlls = all_output[dataset][method]\n",
    "        for p, nll in zip(probs, nlls):\n",
    "            df.append({\n",
    "                \"dataset\": dataset,\n",
    "                \"method\": method,\n",
    "                \"nan_fraction\": p,\n",
    "                \"nll/d\": nll - gpt_nll\n",
    "            })\n",
    "\n",
    "df = pd.DataFrame(df)\n",
    "print(df)\n",
    "\n",
    "df['ll/d'] = -1 * df['nll/d']\n",
    "df['method'] = df['method'].apply(lambda x: name_map[x])\n",
    "\n",
    "print(df)\n",
    "\n",
    "sns.set(style='whitegrid', font_scale=1.25)\n",
    "fig, ax = plt.subplots(1, 1, figsize=(5.5, 3.5))\n",
    "\n",
    "sns.lineplot(\n",
    "    df,\n",
    "    x = \"nan_fraction\",\n",
    "    y = \"ll/d\",\n",
    "    hue=\"method\",\n",
    "    hue_order=['TCN', 'ARIMA', \"N-HiTS\", \"GPT-3\\n(interp.)\", \"GPT-3\\n(NaNs)\"],\n",
    "    errorbar=\"se\",\n",
    "    palette='Dark2',\n",
    "    linewidth=3,\n",
    "    ax=ax,\n",
    ")\n",
    "\n",
    "ax.get_legend().remove()\n",
    "handles, labels = ax.get_legend_handles_labels()\n",
    "\n",
    "handles = handles[:1] + handles[2:3] + handles[1:2] + handles[3:]\n",
    "labels = labels[:1] + labels[2:3] + labels[1:2] + labels[3:]\n",
    "# handles = [val for pair in zip(handles[:2], handles[-2:]) for val in pair] + handles[2:3]\n",
    "# labels = [val for pair in zip(labels[:2], labels[-2:]) for val in pair] + labels[2:3]\n",
    "\n",
    "leg = ax.legend(\n",
    "    handles=handles,\n",
    "    labels=labels,\n",
    "    # markerscale=,\n",
    "    # linewidth=3,\n",
    "    # bbox_to_anchor=(0.5, -0.6),\n",
    "    loc='lower left',\n",
    "    borderaxespad=0.3,\n",
    "    columnspacing=0.5,\n",
    "    ncol=2,\n",
    "    fontsize=15,\n",
    "    # zorder=10,\n",
    ")\n",
    "\n",
    "for legobj in leg.legendHandles:\n",
    "    legobj.set_linewidth(4.0)\n",
    "\n",
    "plt.ylim((-7,1))\n",
    "plt.xlabel('NaN Fraction')\n",
    "plt.ylabel('Log Likelihood / D')\n",
    "\n",
    "plt.savefig('missing_ll.pdf', bbox_inches='tight')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import cloudpickle\n",
    "from data.metrics import calculate_crps\n",
    "from data.small_context import get_datasets\n",
    "\n",
    "datasets = get_datasets()\n",
    "\n",
    "with open(f'eval/missing_expt/missing_full.pkl','rb') as f:\n",
    "    all_output = cloudpickle.load(f)\n",
    "\n",
    "df = []\n",
    "for dsname in ['AirPassengersDataset']:\n",
    "    print(dsname)\n",
    "    output_dict = all_output[dsname]\n",
    "\n",
    "    train, test = datasets[dsname]\n",
    "    ps = output_dict['p']\n",
    "    tmae, crps = defaultdict(list), defaultdict(list)\n",
    "    for seed, inner_dict in output_dict.items():\n",
    "        if seed == 'p':\n",
    "            continue \n",
    "        \n",
    "        # print(seed)\n",
    "        for model, results in inner_dict.items():\n",
    "            # print(model)\n",
    "            if model in ['p','gp-Nan', 'gp']:\n",
    "                continue\n",
    "\n",
    "            # print([x['samples'].shape for x in results])\n",
    "\n",
    "            nlls = [x['NLL/D'] for x in results]\n",
    "            \n",
    "            if 'gp' in model:\n",
    "                samples = [x['samples'] for x in results]\n",
    "            else:\n",
    "                samples = [x['samples'].values for x in results]\n",
    "            \n",
    "            crps[model].append([\n",
    "                calculate_crps(test.values, x, 20) for x in samples\n",
    "            ])\n",
    "            tmae[model].append([\n",
    "                np.abs(test.values-x['median']).mean()/np.abs(test.values).mean() for x in results\n",
    "            ])\n",
    "\n",
    "    \n",
    "    # print(crps)\n",
    "    # print(tmae)\n",
    "    ps = [0.,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9]\n",
    "    for model in crps:\n",
    "        # print(crps[model])\n",
    "        for i, (x, y) in enumerate(zip(crps[model], tmae[model])):\n",
    "        # tmae[model] = np.mean(np.array(tmae[model]), 0)\n",
    "        # crps[model] = np.mean(np.array(crps[model]), 0)\n",
    "            x = np.array(x)\n",
    "            y = np.array(y)\n",
    "\n",
    "            for c, m, p in zip(x, y, ps):\n",
    "                df.append({\n",
    "                    \"dataset\": dsname,\n",
    "                    \"method\": model,\n",
    "                    \"nan_fraction\": p,\n",
    "                    \"crps\": c,\n",
    "                    \"mae\": m,\n",
    "                    \"seed\": i,\n",
    "                })\n",
    "\n",
    "df = pd.DataFrame(df)\n",
    "df['method'] = df['method'].apply(lambda x: name_map[x])\n",
    "\n",
    "sns.set(style='whitegrid', font_scale=1.25)\n",
    "fig, ax = plt.subplots(1, 1, figsize=(5.5, 3.5))\n",
    "\n",
    "sns.lineplot(\n",
    "    df,\n",
    "    x = \"nan_fraction\",\n",
    "    y = \"crps\",\n",
    "    hue=\"method\",\n",
    "    hue_order=['TCN', 'ARIMA', \"N-HiTS\",  \"GPT-3\\n(interp.)\", \"GPT-3\\n(NaNs)\"],\n",
    "    errorbar=\"se\",\n",
    "    palette='Dark2',\n",
    "    linewidth=3,\n",
    "    ax=ax,\n",
    ")\n",
    "\n",
    "ax.get_legend().remove()\n",
    "handles, labels = ax.get_legend_handles_labels()\n",
    "\n",
    "# handles = handles[:1] + handles[2:3] + handles[1:2] + handles[3:]\n",
    "# labels = labels[:1] + labels[2:3] + labels[1:2] + labels[3:]\n",
    "# handles = [val for pair in zip(handles[:2], handles[-2:]) for val in pair] + handles[2:3]\n",
    "# labels = [val for pair in zip(labels[:2], labels[-2:]) for val in pair] + labels[2:3]\n",
    "\n",
    "leg = ax.legend(\n",
    "    handles=handles,\n",
    "    labels=labels,\n",
    "    # markerscale=,\n",
    "    # linewidth=3,\n",
    "    # bbox_to_anchor=(0.5, -0.6),\n",
    "    loc='upper left',\n",
    "    borderaxespad=0.3,\n",
    "    columnspacing=0.5,\n",
    "    ncol=2,\n",
    "    fontsize=15,\n",
    "    # zorder=10,\n",
    ")\n",
    "\n",
    "for legobj in leg.legendHandles:\n",
    "    legobj.set_linewidth(3.0)\n",
    "\n",
    "plt.xlabel('NaN Fraction')\n",
    "plt.ylabel('CRPS')\n",
    "\n",
    "plt.savefig('missing_crps.pdf', bbox_inches='tight')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "linear: 0.9333333333333333\n",
      "log: 0.17647058823529413\n",
      "square: 0.8235294117647058\n",
      "linear_cos: 0.29411764705882354\n",
      "sinc: 0.0\n",
      "sigmoid: 0.05263157894736842\n",
      "beat: 0.0\n",
      "exp: 0.8125\n",
      "gaussian_wave: 0.6\n",
      "sine: 0.125\n",
      "x_times_sine: 0.0\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/var/folders/4z/0371zfqj5mx0rlct4r3qclfm0000gn/T/ipykernel_84564/2487969271.py:59: UserWarning: FixedFormatter should only be used together with FixedLocator\n",
      "  ax.set_xticklabels(\n"
     ]
    },
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 400x350 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import pickle\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "from collections import defaultdict\n",
    "\n",
    "sns.set(style='whitegrid', font_scale=1.)\n",
    "\n",
    "with open(f'../gpt4_cot.pkl','rb') as f:\n",
    "    data_dict = pickle.load(f)\n",
    "\n",
    "for task in data_dict:\n",
    "    answers = [b.split(\":\")[-1].strip() for a,b in data_dict[task]]\n",
    "    acc = np.mean([int(a == task) for a in answers])\n",
    "    print(f\"{task}: {acc}\")\n",
    "\n",
    "df = pd.DataFrame([\n",
    "    {\"method\": \"GPT4 + CoT\", \"Task\": \"Linear\", \"Accuracy\": 0.93},\n",
    "    {\"method\": \"GPT4 + CoT\", \"Task\": \"Square\", \"Accuracy\": 0.82},\n",
    "    {\"method\": \"GPT4 + CoT\", \"Task\": \"Exp\", \"Accuracy\": 0.81}, \n",
    "    {\"method\": \"GPT4 + CoT\", \"Task\": \"Gauss Wave\", \"Accuracy\": 0.60},\n",
    "    {\"method\": \"GPT4 + CoT\", \"Task\": \"Linear Cos\", \"Accuracy\": 0.29},\n",
    "    {\"method\": \"GPT4 + CoT\", \"Task\": \"Log\", \"Accuracy\": 0.18},\n",
    "    {\"method\": \"GPT4 + CoT\", \"Task\": \"Sin\", \"Accuracy\": 0.13},\n",
    "    {\"method\": \"GPT4 + CoT\", \"Task\": \"Sigmoid\", \"Accuracy\": 0.05},\n",
    "    # {\"method\": \"GPT4 + CoT\", \"Task\": \"Sinc\", \"Accuracy\": 0.0},\n",
    "    # {\"method\": \"GPT4 + CoT\", \"Task\": \"Beat\", \"Accuracy\": 0.0},\n",
    "    # {\"method\": \"GPT4 + CoT\", \"Task\": \"X * Sin\", \"Accuracy\": 0.0},\n",
    "])\n",
    "\n",
    "fig, ax = plt.subplots(1, 1, figsize=(4, 3.5))\n",
    "\n",
    "# import IsleOfDogs2_6 palette \n",
    "# from palettable import colorbrewer\n",
    "# palette = colorbrewer.qualitative.Set2_8.mpl_colors\n",
    "\n",
    "#set palette to sns colorblind\n",
    "palette = sns.color_palette(\"colorblind\", 8)[::-1]\n",
    "\n",
    "sns.barplot(\n",
    "    y='Task',\n",
    "    x='Accuracy',\n",
    "    # hue='Type',\n",
    "    palette=palette,\n",
    "    data=df,\n",
    "    ax=ax, \n",
    ")\n",
    "\n",
    "ax.plot([1./11, 1./11], [-0.5, 7.5], color='black', linestyle='--', linewidth=1, label='Random')\n",
    "# ax.set_ylim((-0.5, 7.5))\n",
    "\n",
    "ax.legend(\n",
    "    # loc='lower right', \n",
    "    frameon=True, \n",
    "    framealpha=0.7, \n",
    "    fontsize=15\n",
    ")\n",
    "ax.set_xticklabels(\n",
    "    ['{:,.0%}'.format(x) for x in ax.get_xticks()], \n",
    "    fontsize=14\n",
    ")\n",
    "ax.set_xlabel(ax.get_xlabel(), fontsize=17)\n",
    "\n",
    "ax.set_yticklabels(ax.get_yticklabels(), fontsize=14)\n",
    "ax.set_ylabel(\"\")\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.savefig('gpt4_classification.pdf', dpi=300, bbox_inches='tight')\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "base",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.3"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
